import ij.IJ;
import ij.ImageStack;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;


public class merge_Channel{

	private byte[] blank;
	ImageStack mergeStacks(int w, int h, int d, ImageStack red,
			ImageStack green, ImageStack blue, boolean keep) {
		ImageStack rgb = new ImageStack(w, h);
		int inc = d / 10;
		if (inc < 1)
			inc = 1;
		ColorProcessor cp;
		int slice = 1;
		blank = new byte[w * h];
		byte[] redPixels, greenPixels, bluePixels;
		boolean invertedRed = red != null ? red.getProcessor(1).isInvertedLut()
				: false;
		boolean invertedGreen = green != null ? green.getProcessor(1)
				.isInvertedLut() : false;
				boolean invertedBlue = blue != null ? blue.getProcessor(1)
						.isInvertedLut() : false;
						try {
							for (int i = 1; i <= d; i++) {
								cp = new ColorProcessor(w, h);
								redPixels = getPixels(red, slice, 0);
								greenPixels = getPixels(green, slice, 1);
								bluePixels = getPixels(blue, slice, 2);
								if (invertedRed)
									redPixels = invert(redPixels);
								if (invertedGreen)
									greenPixels = invert(greenPixels);
								if (invertedBlue)
									bluePixels = invert(bluePixels);
								cp.setRGB(redPixels, greenPixels, bluePixels);
								if (keep) {
									slice++;
								} else {
									if (red != null)
										red.deleteSlice(1);
									if (green != null && green != red)
										green.deleteSlice(1);
									if (blue != null && blue != red && blue != green)
										blue.deleteSlice(1);
								}
								rgb.addSlice(null, cp);
								if ((i % inc) == 0)
									IJ.showProgress((double) i / d);
							}
							IJ.showProgress(1.0);
						} catch (OutOfMemoryError o) {
							IJ.outOfMemory("Merge Stacks");
							IJ.showProgress(1.0);
						}
						return rgb;
	}

	byte[] getPixels(ImageStack stack, int slice, int color) {
		if (stack == null)
			return blank;
		Object pixels = stack.getPixels(slice);
		if (!(pixels instanceof int[])) {
			if (pixels instanceof byte[])
				return (byte[]) pixels;
			else {
				ImageProcessor ip = stack.getProcessor(slice);
				ip = ip.convertToByte(true);
				return (byte[]) ip.getPixels();
			}
		} else { // RGB
			byte[] r, g, b;
			int size = stack.getWidth() * stack.getHeight();
			r = new byte[size];
			g = new byte[size];
			b = new byte[size];
			ColorProcessor cp = (ColorProcessor) stack.getProcessor(slice);
			cp.getRGB(r, g, b);
			switch (color) {
			case 0:
				return r;
			case 1:
				return g;
			case 2:
				return b;
			}
		}
		return null;
	}

	byte[] invert(byte[] pixels) {
		byte[] pixels2 = new byte[pixels.length];
		System.arraycopy(pixels, 0, pixels2, 0, pixels.length);
		for (int i = 0; i < pixels2.length; i++)
			pixels2[i] = (byte) (255 - pixels2[i] & 255);
		return pixels2;
	}

}